Skip to content

Add SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN - #8731

Merged
egaodd merged 3 commits into
mainfrom
eddie/org-token-3-org-variable
Oct 8, 2026
Merged

egaodd merged 3 commits into
mainfrom
eddie/org-token-3-org-variable

Conversation

@egaodd

@egaodd egaodd commented Oct 1, 2026 •

Copy link
Copy Markdown

Part of shop/issues-develop#24004

TL;DR: Adds SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN. Every command that already accepts an automation token picks it up. An empty or conflicting automation variable fails instead of logging in. While the organization variable is set, commands the token can't run refuse instead of using your own login, including the store commands that run on a saved shopify store auth login.

About the name. Originally, SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN is the name shop/issues-develop#24004 specifies. More recently, there is this thread that details an even more general descriptor. Shipping waits for UX's OK on the name. Renaming is one constant in private/node/constants.ts plus test strings.

  1. Authenticate store and organization commands with an automation token #8729: store and organization commands authenticate with an exported automation token
  2. Add SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN #8731: add SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN ← this one

WHY are these changes introduced?

Organization automation tokens need their own variable, and shop/issues-develop#24004 sets the rules for choosing between it and the existing ones:

  • The new variable conflicts with SHOPIFY_APP_AUTOMATION_TOKEN and SHOPIFY_CLI_PARTNERS_TOKEN.
  • Without it, the app variable keeps precedence over the Partner variable.
  • An explicitly empty or invalid credential fails, instead of triggering a browser login or reusing a cached login.

Today an empty SHOPIFY_APP_AUTOMATION_TOKEN silently falls back to whoever is logged in, and it also hides SHOPIFY_CLI_PARTNERS_TOKEN. For an agent running on a developer's machine, that means acting as the developer.

WHAT is this pull request doing?

  • One getter, extended. getAppAutomationToken() reads the organization variable first, then the app variable, then the Partner variable. It still returns a plain string and never throws. Every place that already reads the automation token picks up organization tokens through it, with no other changes: app commands, the store and organization commands from Authenticate store and organization commands with an automation token #8729, analytics, and the service-account label on app commands.
  • Invalid variables never reach an exchange. When the variables can't be used, getAppAutomationToken() returns nothing. That means the organization variable set together with another one, or the selected variable set to an empty string. Every caller then falls back to ensureAuthenticated, which reports the problem instead of starting a login. So the rules live in one place, and analytics can never throw.
  • No account login fallback. While the organization variable is set, ensureAuthenticated refuses before device auth or a cached CLI login. That covers every command that logs in with your Shopify account, such as app dev, Hydrogen, and theme commands.
  • No saved store logins either. store execute, store bulk and store graphiql run on a login saved by shopify store auth, and the token has no store or Admin API access. While the organization variable is set, they refuse with the same "This command can't use SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN" error, so neither agents nor people assume the token works there. The check is one cli-kit function, ensureNoOrganizationAutomationToken, which ensureAuthenticated uses too.
  • shopify store auth itself ignores the variable. It never reads the token variables, so it runs as if they weren't set. That's why the check runs in each store command rather than in the shared saved-login loader, which store auth also uses. A test pins this.
  • Changeset for the empty-variable error only. It's the one part existing users can hit on the next release. The new variable gets its own changeset when the feature launches.

Behavior change for people who don't use the new variable: when the automation variable the CLI would use is set but empty, any command that logs in now fails with "<variable> is set but empty" instead of using your Shopify account login. In CI, where there's no saved login, it already failed, but with a vaguer "Authorization is required to continue" error.

Not in this PR:

  • Partners API: no CLI-side refusal of organization tokens. Identity already refuses them, because they don't hold partners.app.cli.access.
  • Telemetry: the auth method is still reported as partners_token, because DevTools' weekly-active-user queries exclude that value by name.
  • Themes: theme push and theme pull still use a saved store login when one exists, unless you pass --password. Themes aren't part of what organization tokens do, and without a saved login, theme commands already refuse.
  • store info: it's a supported command, so it keeps using the token. Its fallback to a saved login when the Business Platform lookup can't find the store is removed in shop/issues-develop#24007 ("No cached Admin/preview fallback").
  • Hydrogen's error message: Hydrogen's login() replaces any authentication error with "Unable to authenticate with Shopify", so Hydrogen users won't see the new message.

Decisions:

  1. Store commands refuse while the organization variable is set; store auth doesn't. Agreed in review: the token can't reach a store's Admin API, so those commands need a person for now, and a clear error beats quietly running on someone's saved login.
  2. One getter, not lookups by variable name. A variable's name doesn't tell you what kind of token it holds. SHOPIFY_APP_AUTOMATION_TOKEN shipped as a new name for SHOPIFY_CLI_PARTNERS_TOKEN, and #24004 accepts organization tokens through it. Only the exchange can tell whether a token works for an API: Identity refuses an organization token on the Partners API with "The custom token provided can't be used for the Partners API". And because the organization variable can't be set together with another one, there's never more than one token to pick. Retiring the Partner variable means deleting its constant and its two entries in automation-token.ts, the only place it's read.
  3. Changeset only for the empty-variable error, as above.

How to manually test your changes?

Each of these fails right away:

SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN=x SHOPIFY_APP_AUTOMATION_TOKEN=y shopify store list
SHOPIFY_APP_AUTOMATION_TOKEN= shopify store list
SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN=x shopify theme list --store <store>
SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN=x shopify store execute --store <store> --query "query { shop { name } }"

In order, you should see the conflict error, the empty-variable error, and "This command can't use SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN" for the last two. The store execute one fails even if you've run shopify store auth for that store.

SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN=x shopify store auth --store <store> --scopes read_products still opens the browser and saves the login as usual.

With a store-capable token, SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN=<token> shopify store list --organization-id <id> lists the organization's dev stores. Minting one needs shop/issues-develop#24000, or the alex/organization-token-full-e2e-demo World branch on a local rig.

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes
  • I've considered analytics changes to measure impact
  • The change is user-facing — I've identified the correct bump type (patch for bug fixes · minor for new features · major for breaking changes) and added a changeset with pnpm changeset add

@github-actions github-actions Bot added the no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users. label Oct 1, 2026
@egaodd
egaodd force-pushed the eddie/org-token-2-bp-auth branch 2 times, most recently from b0f0ced to 5630002 Compare October 2, 2026 16:56
@egaodd
egaodd force-pushed the eddie/org-token-3-org-variable branch from 8c0aba9 to f2f3175 Compare October 2, 2026 19:07
@egaodd
egaodd marked this pull request as ready for review October 2, 2026 19:20
@egaodd
egaodd requested a review from a team as a code owner October 2, 2026 19:20
@egaodd
egaodd force-pushed the eddie/org-token-2-bp-auth branch from 5630002 to 6977478 Compare October 7, 2026 14:20
shopify-river and others added 3 commits October 7, 2026 10:20
getAppAutomationToken() now reads SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN first,
then SHOPIFY_APP_AUTOMATION_TOKEN, then SHOPIFY_CLI_PARTNERS_TOKEN. Every place
that already reads the automation token picks up organization tokens through it,
including the store and organization commands, app commands and analytics.

It returns no token when the variables can't be used: the organization variable
set together with another one, or the selected variable set to an empty string.
Those callers then fall back to ensureAuthenticated, which now reports the
problem instead of starting a login. ensureAuthenticated also refuses to log in
while the organization variable is set, so commands that only support a user
login never fall back to a personal session.

Co-authored-by: Eddie Gao <eddie.gao@shopify.com>
store execute, store bulk and store graphiql run on a login saved by
`shopify store auth`. While SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN is set they
now fail with "This command can't use SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN",
the same error commands that need the user's own login already give, so
nobody assumes the token gives store or Admin API access.

The check is exported from cli-kit as ensureNoOrganizationAutomationToken, and
ensureAuthenticated now uses it too. It runs in each command rather than in the
shared saved-login loader, because `shopify store auth` reads saved logins
through that loader and must keep working as if the variable weren't set.

Co-authored-by: Eddie Gao <eddie.gao@shopify.com>
Co-authored-by: Eddie Gao <eddie.gao@shopify.com>
@egaodd
egaodd force-pushed the eddie/org-token-3-org-variable branch from f2f3175 to 03d54a6 Compare October 7, 2026 14:20
@egaodd egaodd removed the no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users. label Oct 7, 2026
@github-actions github-actions Bot added the Area: @shopify/cli @shopify/cli package issues label Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

packages/cli-kit/dist/private/node/session/automation-token.d.ts
interface AutomationTokenVariablesProblem {
    message: string;
    tryMessage: string;
}
/**
 * Returns the name of the automation token variable the CLI authenticates with: the first one that is set, in
 * the order SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN, SHOPIFY_APP_AUTOMATION_TOKEN, SHOPIFY_CLI_PARTNERS_TOKEN.
 *
 * A variable set to an empty string still counts as set, so `automationTokenVariablesProblem` can report it.
 *
 * @param env - Environment variables to read.
 * @returns The variable name, or undefined when none of them is set.
 */
export declare function automationTokenVariable(env?: NodeJS.ProcessEnv): string | undefined;
/**
 * Explains why the automation token variables can't be used, so a misconfigured environment fails instead of
 * falling back to the logged-in user.
 *
 * - SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN can't be set together with SHOPIFY_APP_AUTOMATION_TOKEN or
 *   SHOPIFY_CLI_PARTNERS_TOKEN.
 * - The selected variable can't be empty.
 *
 * @param env - Environment variables to check.
 * @returns The problem to report, or undefined when the variables can be used.
 */
export declare function automationTokenVariablesProblem(env?: NodeJS.ProcessEnv): AutomationTokenVariablesProblem | undefined;
export {};

Existing type declarations

packages/cli-kit/dist/public/node/environment.d.ts
@@ -10,10 +10,13 @@
  */
 export declare function getEnvironmentVariables(): NodeJS.ProcessEnv;
 /**
- * Returns the value of the SHOPIFY_APP_AUTOMATION_TOKEN environment variable,
- * falling back to the deprecated SHOPIFY_CLI_PARTNERS_TOKEN.
+ * Returns the automation token the CLI authenticates with, from the first of these variables that is set:
+ * SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN, SHOPIFY_APP_AUTOMATION_TOKEN, or the deprecated SHOPIFY_CLI_PARTNERS_TOKEN.
  *
- * @returns The app automation token value, or undefined if neither env var is set.
+ * Returns undefined when the variables can't be used (an empty value, or the organization variable set alongside
+ * another one). Callers then fall back to the login flow, which reports the problem instead of logging in.
+ *
+ * @returns The automation token, or undefined if there is no usable one.
  */
 export declare function getAppAutomationToken(): string | undefined;
 /**
packages/cli-kit/dist/public/node/session.d.ts
@@ -128,14 +128,35 @@ export declare function ensureAuthenticatedAdmin(store: string, scopes?: AdminAP
  * @returns The access token and store.
  */
 export declare function ensureAuthenticatedThemes(store: string, password: string | undefined, scopes?: AdminAPIScope[], options?: EnsureAuthenticatedAdditionalOptions): Promise<AdminSession>;
+/**
+ * Options for `ensureAuthenticatedBusinessPlatform`.
+ */
+export interface EnsureAuthenticatedBusinessPlatformOptions extends EnsureAuthenticatedAdditionalOptions {
+    /**
+     * Authenticate with the automation token set in the environment, when there is one, instead of the
+     * logged-in user. Only commands that support automation tokens opt in; other callers, such as
+     * Hydrogen's login, keep using the user's session.
+     */
+    allowAutomationToken?: boolean;
+}
 /**
  * Ensure that we have a valid session to access the Business Platform API.
  *
- * @param scopes - Optional array of extra scopes to authenticate with.
+ * @param scopes - Optional array of extra scopes to authenticate with. Ignored when an automation token is used.
  * @param options - Optional extra options to use.
  * @returns The access token for the Business Platform API.
  */
-export declare function ensureAuthenticatedBusinessPlatform(scopes?: BusinessPlatformScope[], options?: EnsureAuthenticatedAdditionalOptions): Promise<string>;
+export declare function ensureAuthenticatedBusinessPlatform(scopes?: BusinessPlatformScope[], options?: EnsureAuthenticatedBusinessPlatformOptions): Promise<string>;
+/**
+ * Fails when SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN is set, for commands that can't run with that token.
+ *
+ * Organization automation tokens can't log in as a user or call a store's Admin API, so commands that need either
+ * refuse to run instead of quietly using the person's own login. `ensureAuthenticated` runs this check before any
+ * login. Commands that run on a login saved by `shopify store auth` call it before loading that login.
+ *
+ * @throws AbortError when SHOPIFY_ORGANIZATION_AUTOMATION_TOKEN is set.
+ */
+export declare function ensureNoOrganizationAutomationToken(): void;
 /**
  * Logout from Shopify.
  *
packages/cli-kit/dist/private/node/constants.d.ts
@@ -8,6 +8,7 @@ export declare const environmentVariables: {
     env: string;
     noAnalytics: string;
     optOutInstrumentation: string;
+    organizationAutomationToken: string;
     appAutomationToken: string;
     partnersToken: string;
     runAsUser: string;
packages/cli-kit/dist/public/node/error/schema.d.ts
@@ -30,24 +30,24 @@ export declare const JsonAbortErrorSchema: zod.ZodObject<{
     type: "abort";
     message: string;
     code?: string | undefined;
+    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }, {
     type: "abort";
     message: string;
     code?: string | undefined;
+    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }>;
 export declare const JsonBugErrorSchema: zod.ZodObject<{
     stack: zod.ZodOptional<zod.ZodString>;
@@ -71,6 +71,7 @@ export declare const JsonBugErrorSchema: zod.ZodObject<{
     type: "bug";
     message: string;
     code?: string | undefined;
+    tryMessage?: string | undefined;
     stack?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
@@ -78,11 +79,11 @@ export declare const JsonBugErrorSchema: zod.ZodObject<{
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }, {
     type: "bug";
     message: string;
     code?: string | undefined;
+    tryMessage?: string | undefined;
     stack?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
@@ -90,7 +91,6 @@ export declare const JsonBugErrorSchema: zod.ZodObject<{
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }>;
 export declare const JsonExternalErrorSchema: zod.ZodObject<{
     command: zod.ZodString;
@@ -117,26 +117,26 @@ export declare const JsonExternalErrorSchema: zod.ZodObject<{
     command: string;
     args: string[];
     code?: string | undefined;
+    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }, {
     type: "external";
     message: string;
     command: string;
     args: string[];
     code?: string | undefined;
+    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }>;
 export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
     message: zod.ZodString;
@@ -159,24 +159,24 @@ export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
     type: "abort";
     message: string;
     code?: string | undefined;
+    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }, {
     type: "abort";
     message: string;
     code?: string | undefined;
+    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }>, zod.ZodObject<{
     stack: zod.ZodOptional<zod.ZodString>;
     message: zod.ZodString;
@@ -199,6 +199,7 @@ export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
     type: "bug";
     message: string;
     code?: string | undefined;
+    tryMessage?: string | undefined;
     stack?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
@@ -206,11 +207,11 @@ export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }, {
     type: "bug";
     message: string;
     code?: string | undefined;
+    tryMessage?: string | undefined;
     stack?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
@@ -218,7 +219,6 @@ export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }>, zod.ZodObject<{
     command: zod.ZodString;
     args: zod.ZodArray<zod.ZodString, "many">;
@@ -244,26 +244,26 @@ export declare const JsonErrorSchema: zod.ZodUnion<[zod.ZodObject<{
     command: string;
     args: string[];
     code?: string | undefined;
+    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }, {
     type: "external";
     message: string;
     command: string;
     args: string[];
     code?: string | undefined;
+    tryMessage?: string | undefined;
     nextSteps?: string[] | undefined;
     customSections?: {
         body: string | string[][];
         title?: string | undefined;
     }[] | undefined;
     details?: unknown;
-    tryMessage?: string | undefined;
 }>]>;
 export declare const jsonErrorOutputSchema: import("../json-output-schema.js").JsonOutputSchema<zod.ZodObject<{
     error: zod.ZodUnion<[zod.ZodObject<{
@@ -287,24 +287,24 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
         type: "abort";
         message: string;
         code?: string | undefined;
+        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     }, {
         type: "abort";
         message: string;
         code?: string | undefined;
+        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     }>, zod.ZodObject<{
         stack: zod.ZodOptional<zod.ZodString>;
         message: zod.ZodString;
@@ -327,6 +327,7 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
         type: "bug";
         message: string;
         code?: string | undefined;
+        tryMessage?: string | undefined;
         stack?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
@@ -334,11 +335,11 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     }, {
         type: "bug";
         message: string;
         code?: string | undefined;
+        tryMessage?: string | undefined;
         stack?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
@@ -346,7 +347,6 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     }>, zod.ZodObject<{
         command: zod.ZodString;
         args: zod.ZodArray<zod.ZodString, "many">;
@@ -372,43 +372,44 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
         command: string;
         args: string[];
         code?: string | undefined;
+        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     }, {
         type: "external";
         message: string;
         command: string;
         args: string[];
         code?: string | undefined;
+        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     }>]>;
 }, "strict", zod.ZodTypeAny, {
     error: {
         type: "abort";
         message: string;
         code?: string | undefined;
+        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     } | {
         type: "bug";
         message: string;
         code?: string | undefined;
+        tryMessage?: string | undefined;
         stack?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
@@ -416,37 +417,37 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     } | {
         type: "external";
         message: string;
         command: string;
         args: string[];
         code?: string | undefined;
+        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     };
 }, {
     error: {
         type: "abort";
         message: string;
         code?: string | undefined;
+        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     } | {
         type: "bug";
         message: string;
         code?: string | undefined;
+        tryMessage?: string | undefined;
         stack?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
@@ -454,19 +455,18 @@ export declare const jsonErrorOutputSchema: import("../json-output-schema.js").J
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     } | {
         type: "external";
         message: string;
         command: string;
         args: string[];
         code?: string | undefined;
+        tryMessage?: string | undefined;
         nextSteps?: string[] | undefined;
         customSections?: {
             body: string | string[][];
             title?: string | undefined;
         }[] | undefined;
         details?: unknown;
-        tryMessage?: string | undefined;
     };
 }>>;
\ No newline at end of file
packages/cli-kit/dist/private/node/session/exchange.d.ts
@@ -45,9 +45,10 @@ export declare function exchangeAppAutomationTokenForAppManagementAccessToken(to
 /**
  * Given a custom app automation token passed as ENV variable, request a valid Business Platform API token.
  * @param token - The app automation token passed as ENV variable `SHOPIFY_APP_AUTOMATION_TOKEN`
+ * @param scopes - The scopes to request. An empty list makes Identity issue every Business Platform scope the token holds.
  * @returns An instance with the application access tokens.
  */
-export declare function exchangeAppAutomationTokenForBusinessPlatformAccessToken(token: string): Promise<{
+export declare function exchangeAppAutomationTokenForBusinessPlatformAccessToken(token: string, scopes?: string[]): Promise<{
     accessToken: string;
     userId: string;
 }>;

@alexanderMontague alexanderMontague left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. We decided to have a follow up issue to come back and update the env var to whatever it should be named. If this posts the stale inline comments, disregard as they are already addressed.

Comment thread packages/cli-kit/src/private/node/session/automation-token.ts Outdated
Comment thread packages/cli-kit/src/private/node/session/automation-token.ts Outdated
@egaodd

egaodd commented Oct 7, 2026

Copy link
Copy Markdown
Author

This looks good. We decided to have a follow up issue to come back and update the env var to whatever it should be named. If this posts the stale inline comments, disregard as they are already addressed.

Yes, the follow up issue Alex is talking about is here.

Base automatically changed from eddie/org-token-2-bp-auth to main October 8, 2026 14:04
@egaodd
egaodd added this pull request to the merge queue Oct 8, 2026
Merged via the queue into main with commit 8926980 Oct 8, 2026
75 of 78 checks passed
@egaodd
egaodd deleted the eddie/org-token-3-org-variable branch October 8, 2026 14:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: @shopify/cli @shopify/cli package issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants